steps:
  - task: NodeTool@0
    inputs:
      versionSource: fromFile
      versionFilePath: .nvmrc
      nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download

  - task: SFP.build-tasks.esrpclient-tools-task.EsrpClientTool@2
    displayName: "Use EsrpClient"

  - task: AzureKeyVault@1
    displayName: "Azure Key Vault: Get Secrets"
    inputs:
      azureSubscription: "vscode-builds-subscription"
      KeyVaultName: vscode-build-secrets
      SecretsFilter: "github-distro-mixin-password,esrp-aad-username,esrp-aad-password"

  - task: AzureKeyVault@1
    displayName: "Azure Key Vault: Get Secrets"
    inputs:
      azureSubscription: "vscode-builds-subscription"
      KeyVaultName: vscode-build-packages
      SecretsFilter: "vscode-esrp,c24324f7-e65f-4c45-8702-ed2d4c35df99"

  # allow-any-unicode-next-line
  - pwsh: Write-Host "##vso[build.addbuildtag]🚀"
    displayName: Add build tag

  - pwsh: node build/npm/setupBuildYarnrc
    displayName: Prepare build dependencies

  - pwsh: yarn
    workingDirectory: build
    displayName: Install build dependencies

  - download: current
    patterns: "**/artifacts_processed_*.txt"
    displayName: Download all artifacts_processed text files

  - task: AzureCLI@2
    displayName: Fetch secrets
    inputs:
      azureSubscription: "vscode-builds-subscription"
      scriptType: pscore
      scriptLocation: inlineScript
      addSpnToEnvironment: true
      inlineScript: |
        Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId"
        Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId"
        Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;issecret=true]$env:servicePrincipalKey"

  - pwsh: |
      . build/azure-pipelines/win32/exec.ps1

      if (Test-Path "$(Pipeline.Workspace)/artifacts_processed_*/artifacts_processed_*.txt") {
        Write-Host "Artifacts already processed so a build must have already been created."
        return
      }

      $VERSION = node -p "require('./package.json').version"
      Write-Host "Creating build with version: $VERSION"
      exec { node build/azure-pipelines/common/createBuild.js $VERSION }
    env:
      AZURE_TENANT_ID: "$(AZURE_TENANT_ID)"
      AZURE_CLIENT_ID: "$(AZURE_CLIENT_ID)"
      AZURE_CLIENT_SECRET: "$(AZURE_CLIENT_SECRET)"
    displayName: Create build if it hasn't been created before

  - pwsh: |
      $ErrorActionPreference = "Stop"
      $CertCollection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
      $AuthCertBytes = [System.Convert]::FromBase64String("$(vscode-esrp)")
      $CertCollection.Import($AuthCertBytes, $null, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable -bxor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet)
      $RequestSigningCertIndex = $CertCollection.Count
      $RequestSigningCertBytes = [System.Convert]::FromBase64String("$(c24324f7-e65f-4c45-8702-ed2d4c35df99)")
      $CertCollection.Import($RequestSigningCertBytes, $null, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable -bxor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet)
      $CertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine")
      $CertStore.Open("ReadWrite")
      $CertStore.AddRange($CertCollection)
      $CertStore.Close()
      $AuthCertSubjectName = $CertCollection[0].Subject
      $RequestSigningCertSubjectName = $CertCollection[$RequestSigningCertIndex].Subject
      Write-Host "##vso[task.setvariable variable=RELEASE_AUTH_CERT_SUBJECT_NAME]$AuthCertSubjectName"
      Write-Host "##vso[task.setvariable variable=RELEASE_REQUEST_SIGNING_CERT_SUBJECT_NAME]$RequestSigningCertSubjectName"
    displayName: Import certificates

  - pwsh: node build/azure-pipelines/common/publish.js
    env:
      GITHUB_TOKEN: "$(github-distro-mixin-password)"
      AZURE_TENANT_ID: "$(AZURE_TENANT_ID)"
      AZURE_CLIENT_ID: "$(AZURE_CLIENT_ID)"
      AZURE_CLIENT_SECRET: "$(AZURE_CLIENT_SECRET)"
      SYSTEM_ACCESSTOKEN: $(System.AccessToken)
      RELEASE_TENANT_ID: "$(PRSS_RELEASE_TENANT_ID)"
      RELEASE_CLIENT_ID: "$(PRSS_RELEASE_CLIENT_ID)"
      RELEASE_AUTH_CERT_SUBJECT_NAME: "$(RELEASE_AUTH_CERT_SUBJECT_NAME)"
      RELEASE_REQUEST_SIGNING_CERT_SUBJECT_NAME: "$(RELEASE_REQUEST_SIGNING_CERT_SUBJECT_NAME)"
      PROVISION_TENANT_ID: "$(PRSS_PROVISION_TENANT_ID)"
      PROVISION_AAD_USERNAME: "$(esrp-aad-username)"
      PROVISION_AAD_PASSWORD: "$(esrp-aad-password)"
    displayName: Process artifacts
    retryCountOnTaskFailure: 3

  - task: 1ES.PublishPipelineArtifact@1
    inputs:
      targetPath: $(Pipeline.Workspace)/artifacts_processed_$(System.StageAttempt)/artifacts_processed_$(System.StageAttempt).txt
      artifactName: artifacts_processed_$(System.StageAttempt)
      sbomEnabled: false
    displayName: Publish the artifacts processed for this stage attempt
    condition: always()

  - pwsh: |
      $ErrorActionPreference = 'Stop'

      # Determine which stages we need to watch
      $stages = @(
        if ($env:VSCODE_BUILD_STAGE_WINDOWS -eq 'True') { 'Windows' }
        if ($env:VSCODE_BUILD_STAGE_LINUX -eq 'True') { 'Linux' }
        if ($env:VSCODE_BUILD_STAGE_LINUX_LEGACY_SERVER -eq 'True') { 'LinuxLegacyServer' }
        if ($env:VSCODE_BUILD_STAGE_ALPINE -eq 'True') { 'Alpine' }
        if ($env:VSCODE_BUILD_STAGE_MACOS -eq 'True') { 'macOS' }
        if ($env:VSCODE_BUILD_STAGE_WEB -eq 'True') { 'Web' }
      )
      Write-Host "Stages to check: $stages"

      # Get the timeline and see if it says the other stage completed
      $timeline = Invoke-RestMethod "$($env:BUILDS_API_URL)timeline?api-version=6.0" -Headers @{
        Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
      }  -MaximumRetryCount 5 -RetryIntervalSec 1

      $failedStages = @()
      foreach ($stage in $stages) {
        $didStageFail = $timeline.records | Where-Object {
          $_.name -eq $stage -and $_.type -eq 'stage' -and $_.result -ne 'succeeded' -and $_.result -ne 'succeededWithIssues'
        }

        if($didStageFail) {
          $failedStages += $stage
          Write-Host "'$stage' failed!"
          Write-Host $didStageFail
        } else {
          Write-Host "'$stage' did not fail."
        }
      }

      if ($failedStages.Length) {
        throw "Failed stages: $($failedStages -join ', '). This stage will now fail so that it is easier to retry failed jobs."
      }
    env:
      SYSTEM_ACCESSTOKEN: $(System.AccessToken)
    displayName: Determine if stage should succeed
